package com.haotian.coder.utils;

import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;

import com.haotian.coder.exception.BusinessException;
import com.haotian.coder.exception.ErrorCode;
import com.haotian.coder.exception.ThrowUtils;
import io.github.bonigarcia.wdm.WebDriverManager;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.stereotype.Component;

import java.io.File;
import java.time.Duration;

@Slf4j
@Component
public class WebScreenshotUtils {

    private static final WebDriver webDriver;

    static {
        final int DEFAULT_WIDTH = 1600;
        final int DEFAULT_HEIGHT = 900;
        webDriver = initChromeDriver(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }

    /**
     * 初始化 Chrome 浏览器驱动
     */
    private static WebDriver initChromeDriver(int width, int height) {
        try {
            // 自动管理 ChromeDriver
            System.setProperty("wdm.chromeDriverMirrorUrl","https://registry.npmmirror.com/binary.html?path=chromedriver");
            WebDriverManager.chromedriver().useMirror().setup();

            // 配置 Chrome 选项
            ChromeOptions options = new ChromeOptions();
            // 无头模式
            options.addArguments("--headless");
            // 禁用GPU（在某些环境下避免问题）
            options.addArguments("--disable-gpu");
            // 禁用沙盒模式（Docker环境需要）
            options.addArguments("--no-sandbox");
            // 禁用开发者shm使用
            options.addArguments("--disable-dev-shm-usage");
            // 设置窗口大小
            options.addArguments(String.format("--window-size=%d,%d", width, height));
            // 禁用扩展
            options.addArguments("--disable-extensions");
            // 设置用户代理
            options.addArguments("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
            // 创建驱动
            WebDriver driver = new ChromeDriver(options);
            // 设置页面加载超时
            driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(30));
            // 设置隐式等待
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
            return driver;
        } catch (Exception e) {
            log.error("初始化 Chrome 浏览器失败", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "初始化 Chrome 浏览器失败");
        }
    }

    public static String saveAndCompressScreenshot(String webUrl) {
        try {
            ThrowUtils.throwIf(webUrl == null, ErrorCode.PARAMS_ERROR, "网址不能为空");
            // 创建临时目录
            String rootPath = System.getProperty("user.dir") + File.separator + "tmp" + File.separator + "Screenshot";
            // 图片后缀
            String IMAGE_SUFFIX = ".png";
            // 原始图片路径
            String originalImagePath = rootPath + File.separator + RandomUtil.randomString(6) + IMAGE_SUFFIX;
            // 访问网页
            webDriver.get(webUrl);
            // 等待网页加载
            waitForPageLoad(webDriver);
            // 网页截图
            byte[] screenShots = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.BYTES);
            // 保存原始图片
            saveImage(screenShots, originalImagePath);
            log.info("原始图片保存成功:{}", originalImagePath);
            // 压缩图片
            // 压缩图片路径，区分原始图片
            final String COMPRESS_SUFFIX = "_Compress.jpg";
            String CompressImagePath = rootPath + File.separator + RandomUtil.randomString(6) + COMPRESS_SUFFIX;
            CompressImage(originalImagePath, CompressImagePath);
            // 删除原始图片只保存压缩图片
            FileUtil.del(originalImagePath);

            return CompressImagePath;
        } catch (Exception e) {
            log.error("保存截图失败{},url->{}", e.getMessage(), webUrl);
            return null;
        }
    }

    private static void waitForPageLoad(WebDriver Driver) {
        try {
            // 创建对象
            WebDriverWait wait = new WebDriverWait(Driver, Duration.ofSeconds(10));
            // 等待加载
            wait.until(webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
            // 再次等待两秒确保加载完成
            Thread.sleep(2000);
            log.info("页面加载完成");
        } catch (InterruptedException e) {
            log.error("等待页面加载失败");
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "等待页面加载失败");
        }
    }

    /**
     * 保存图片
     *
     * @param imageBytes
     * @param path
     */
    private static void saveImage(byte[] imageBytes, String path) {
        try {
            FileUtil.writeBytes(imageBytes, path);
        } catch (Exception e) {
            log.error("保存图片失败:{}", path);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "保存图片失败");
        }
    }

    /**
     * 压缩图片
     */
    private static void CompressImage(String orinalImagePath, String CompressImagePath) {

        final float COMPRESS_QUALITY = 0.3f;

        try {
            ImgUtil.compress(FileUtil.file(orinalImagePath), FileUtil.file(CompressImagePath), COMPRESS_QUALITY);
        } catch (Exception e) {
            log.error("压缩图片失败,{}->{}", orinalImagePath, CompressImagePath);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "压缩图片失败");
        }
    }

    @PreDestroy
    public void destroy() {
        webDriver.quit();
    }


}
